/*
 * @Author: Hero2633 2633105413@qq.com
 * @Date: 2024-05-24 14:42:59
 * @LastEditors: Hero2633 2633105413@qq.com
 * @LastEditTime: 2024-05-24 15:41:04
 * @FilePath: /Cloud/hotManger.hpp
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
/*
热点管理模块:
功能：遍历备份文件,检测每个备份文件是否是非热点文件，如果是非热点文件，那么将其压缩，然后存放在压缩路径下面,同时删除备份路径下的源文件,修改该备份文件的
备份信息;
然后的话,遍历备份文件有两种方式:
    1. 遍历数据管理模块;
    2. 遍历备份文件夹中的备份文件
这里选择第二种遍历方式,主要是因为:
1. 要是我们确实备份了文件,但是备份信息丢失了怎么办,选择第一种的话就无法解决这个问题，对于第一种遍历来说丢失了旧真丢失了，没有被遍历到的
文件，就只能一直当作热点文件，不合适;
2. 数据管理模块中的最近一次访问时间是固定的是备份文件第一次备份的时间，而我们要的是动态的最近一次访问时间

主要流程:
    1. 遍历备份文件夹，获取当前文件夹下的备份文件路径;
    2. 判断当前备份文件是不是非热点文件
       是非热点文件:压缩、将压缩文件存入备份目录、删除该备份文件在备份路径下的源文件、修改数据模块中的备份文件信息;
       不是非热点文件:continue

要实现这些功能，需要以下属性:
1. 备份文件夹路径
2. 压缩文件夹路径
3. 压缩文件后缀
4. 数据管理模块

这些数据都可以通过配置模块获取，因此在热点模块中可以不要这些属性，因此我们可以考虑将热点模块设计成仿函数
*/
#pragma once
#include <cstdio>
#include <chrono>
#include <thread>
#include <memory>
#include "util.hpp"
#include "config.hpp"
#include "dataManger.hpp"
namespace Cloud
{
    class HotManger
    {
        bool isHotFile(const Cloud::blackupFileMsg &e)
        {
            time_t curTime = time(NULL);
            auto &cf = Config::getInstance();
            time_t hotTime = cf.hotTime();
            if (curTime - e._aTime > hotTime)
                return false;
            return true;
        }

    public:
        HotManger(DataManger *ptr, const std::string &backupPath, const std::string &compressPath) : _ptr(ptr), _backupPath(backupPath), _compressPath(compressPath) {}
        void operator()()
        {
            while (true)
            {
                // 1. 获取备份文件夹中的所有普通文件
                fileUtil f1(_backupPath);
                if (f1.exists() == false)
                    f1.createDirectory();
                fileUtil f2(_compressPath);
                if (f2.exists() == false)
                    f2.createDirectory();
                std::vector<std::string> array;
                f1.scanDirectory(&array);
                for (auto &path : array)
                {
                    blackupFileMsg e;
                    // 文件对应的信息不存在，则需要重新插入
                    if (_ptr->getBackupFileMsgByRealPath(path, &e) == false)
                    {
                        fileUtil f2(path);
                        blackupFileMsg e2(path, _compressPath + f2.filename() + Config::getInstance().suffixName());
                        _ptr->insert(e2);
                    }
                    else
                    {
                        if (isHotFile(e))
                            continue;
                        else
                        {
                            // 1. 将数据进行压缩处理
                            fileUtil f2(path);
                            fileUtil f3(_compressPath);
                            if (!f3.exists())
                                f3.createDirectory();
                            std::string compressFilePath = _compressPath + f2.filename() + Config::getInstance().suffixName();
                            f2.compress(compressFilePath);

                            // 2. 删除热点文件
                            remove(path.c_str());
                            // 3. 更新文件信息
                            e._aTime = time(nullptr);
                            e._compressFlag = true;
                            _ptr->update(e);
                        }
                    }
                }
                std::this_thread::sleep_for(std::chrono::milliseconds(1000));
            }
        }

    private:
        std::shared_ptr<DataManger> _ptr;
        std::string _backupPath;
        std::string _compressPath;
    };
}